home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-18 | 39.7 KB | 1,278 lines | [TEXT/MPS ] |
- /******************************************************************************
-
- NAME:
- Infinity Windoid 2.3
-
- FILE:
- InfinityWindoid.c
-
- WRITTEN BY:
- Troy Gaul
- Infinity Systems
-
- © 1991-93 Infinity Systems
- All rights reserved.
-
- DESCRIPTION:
- This file contains the source for a standalone code resource that
- conforms to a Window DEFinition (WDEF), as defined by Apple Computer
- in Inside Macintosh.
-
- It provides a 'windoid' appearance. A windoid is a floating window
- that appears above document windows in an application and is commonly
- used for things like tool palettes, information windows, and the like.
-
- The WDEF included in the ResEdit file can be used as-is, but if a zoom
- box is to be used, you will probably want to change the behavior of
- what is included (by default, it zooms smaller rather than larger as
- described below). This WDEF is created for System 6 and later, but it
- would be easy to modify it for earlier systems if this is important.
-
- FEATURES:
- • Supports System 7-style coloring of windows.
- • In System 7, the tinge color set by the user in the Color control
- panel is used.
- • Close box can be enabled from NewWindow by setting goAwayFlag.
- • Zoom box (special case) implemented, utilized by adding zoomDocProc
- to the proc ID used to create the windoid.
- • Title bar can appear along the left of the window if 1 is added to
- the proc ID (with or without a zoom box).
- • For MacApp users, the left/top behavior of the proc ID can be
- switched.
- • System 6 coloring scheme is also supported (can be set in Kolor or
- a similar control panel).
- • In System 7, DeviceLoop is used so the windoid will be drawn
- correctly even when it crosses monitors of differing depths.
- • In System 7, indexed color tables are checked to see if there are
- enough different colors to display the color version (like the
- system WDEF).
-
- -------------------------------------------------------------------------------
-
- HOW TO CONTACT THE AUTHOR:
- Troy Gaul
- Infinity Systems
-
- MicroFrontier, Inc.
- 3401 101st Street
- Suite E
- Des Moines, IA 50322
- (515) 270-8109
-
- Internet: t-gaul@grayhawk.rent.com
-
- AppleLink: mfrontier
-
- America Online: ntwing
- mfrontier
-
- FAX: (515) 278-6828
-
- ******************************************************************************/
-
-
- //*****************************************************************************
- // Include files
- //-----------------------------------------------------------------------------
-
- #define SystemSixOrLater 1
- // This is used so that we can cut down on the code size in MPW. If you
- // think support for earlier systems is important, get rid of this.
- // Note: for this define to work under THINK C, MacHeaders should NOT
- // be included.
-
- //-----------------------------------------------------------------------------
-
- #include <Memory.h>
- #include <QuickDraw.h>
- #include <OSUtils.h>
- #include <Windows.h>
- #include <Palettes.h>
- #include <ToolUtils.h>
- #include <Desk.h>
-
- /******************************************************************************
- // Conditional Compilation Options
- //-----------------------------------------------------------------------------
-
- The #define's you may make include:
-
- ALLOW_ZOOM - This option creates a windoid that supports a zoombox.
- To add the zoombox to a windoid, add zoomDocProc to the
- procID when creating the window. The application is
- responsible for setting the user state and standard state
- Rects of the window for zooming. (When a new window is
- created, both of these are initialized to the bounds
- of the window. See the README for more information).
-
- STAYPUT_ZOOM - This option will cause both the user and standard Rects to
- be changed together, causing the zoomed in and out state
- to have the same topLeft at all times. If this is not set,
- the standard and user states have their own 'memories'.
- (Note: this behavior is not fully tested.)
-
- MFI_ZOOM - This will cause the WDEF to handle the zoom box in the way
- expected by MicroFrontier applications (the same way as
- version 2.2). That is, the other state that is used is one
- which has a title bar with a small area (in which the host
- program displays a label for the windoid).
-
- ALLOW_VERT - This determines if the code that is compiled will support
- a palette that has a vertical title bar along the left
- side of the window (rather than the top). To create such
- a window, add one to the varcode that is used.
-
- MACAPP_STYLE - This determines if the varcodes that are supported are
- the one's I consider 'normal' or the ones MacApp's
- windoid WDEF knows about. Note, however, that this code
- only supports the 'smaller', title-less version that
- is available in MacApp's.
-
- THINK_STYLE - This creates a version of the WDEF that is totally
- compatible with the varcodes used in the windoid WDEF
- included with the THINK environments. Two things are done:
- varcode 0 gives a normal titlebar, varcode 2 gives a
- titlebar down the left side, and other varcodes (i.e.
- 1,3,4,5,6,7) give no titlebar at all. (Note that in my
- version, a zoom box may also be used with this style.)
- Also, for the THINK style, ALWAYS_HILITE is also set, as
- this is how theirs works.
-
- ALWAYS_HILITE - This will cause a windoid to be created that will always
- draw its title bar with gadgets and all. Normally, the
- windoid will draw the titlebar and frame in gray and
- empty when the window is not hilighted (like normal
- windows). Some programs, however, don't keep their
- windoids properly hilighted, so this will make them
- appear to always be active.
-
- VERS_2_2_COMPATIBLE - This creates a version of the WDEF that is
- functionally compatible with the version 2.2 windoid that
- I released. The only issue involved is the way the zooming
- is handled.
-
- -----------------------------------------------------------------------------*/
-
- #define ALLOW_ZOOM
- #define ALLOW_VERT
-
- #define VERS_2_2_COMPATIBLE
-
- //-----------------------------------------------------------------------------
-
- #ifdef VERS_2_2_COMPATIBLE
- #ifndef MFI_ZOOM
- #define MFI_ZOOM
- #endif
-
- #ifndef STAYPUT_ZOOM
- #define STAYPUT_ZOOM
- #endif
- #endif
-
- //-----------------------------------------------------------------------------
-
- #ifdef THINK_STYLE
- #ifndef ALLOW_VERT
- #define ALLOW_VERT
- #endif
-
- #ifndef ALWAYS_HILITE
- #define ALWAYS_HILITE
- #endif
-
- #ifdef MACAPP_STYLE
- #undef MACAPP_STYLE
- #endif
- #endif
-
- //-----------------------------------------------------------------------------
-
- #ifdef MACAPP_STYLE
- #ifdef ALLOW_VERT
- #undef ALLOW_VERT
- #endif
-
- #ifdef ALWAYS_HILITE
- #undef ALWAYS_HILITE
- #endif
- #endif
-
- //*****************************************************************************
- // Constants
- //-----------------------------------------------------------------------------
-
- #define kTitleHeight 11
- // This is the height of the windoid's titlebar.
-
- #define kGadgetInset 2
- // inset from top/bottom of titlebar (with titlebar on top of window)
- #define kGadgetMargin 6
- // space between edge and gadget
- #define kGadgetSize (kTitleHeight - (2 * kGadgetInset))
-
- //-----------------------------------------------------------------------------
- // Color table tinge percentage constants
- //-----------------------------------------------------------------------------
-
- #define wTitleBarLightPct 0x1
- #define wTitleBarDarkPct 0x8
- #define wCloseBoxColor 0x5
- #define wXedBoxPct 0x8
- #define wInactiveFramePct 0xA
-
- //-----------------------------------------------------------------------------
- // Color table constants
- //-----------------------------------------------------------------------------
-
- enum {
- wHiliteColorLight = 5,
- wHiliteColorDark,
- wTitleBarLight,
- wTitleBarDark,
- wDialogLight,
- wDialogDark,
- wTingeLight,
- wTingeDark
- };
- // These are the constants defined in the Apple technical note regarding
- // Color, Windows, and System 7. Last I checked, they weren't in an Apple
- // header file. (But the ones < 5 are, from the previous, pre-System 7
- // coloring scheme.)
-
- //-----------------------------------------------------------------------------
- // Style variation constants
- //-----------------------------------------------------------------------------
-
- enum {
- blackandwhite = 0,
- sys7color,
- sys6color
- };
- // These constants represent the three types of window 'colorings' we
- // support.
-
- //-----------------------------------------------------------------------------
- // MacApp style variations
- //-----------------------------------------------------------------------------
-
- #define kMacApp_toggleTBar 0x1 // bit 0 tells us whether to hilite/unhilite title bar
- #define kMacApp_hasTallTBar 0x2 // bit 1 is tall title bar bit (unsupported)
- #define kMacApp_hasGrow 0x4 // bit 2 is grow bit (std grow bit, unsupported)
- #define kMacApp_hasZoom 0x8 // bit 3 is zoom bit (standard zoom bit)
-
- //*****************************************************************************
- // Structures
- //-----------------------------------------------------------------------------
-
- typedef struct WindoidData {
- WStateData wState;
- unsigned int closeToggle : 1;
- unsigned int zoomToggle : 1;
- unsigned int isSystem7 : 1;
- unsigned int hasCQD : 1;
- unsigned int isHoriz : 1;
- unsigned int ignoreHilite : 1;
- unsigned int hasTitlebar : 1;
- } WindoidData, **WindoidDataHandle;
-
- #define WindData (**(WindoidDataHandle)(window->dataHandle))
- // This macro is used so I can access the 'globals' easily. Note: the
- // variable containing the window must be 'window', and it must be in
- // scope at the time of the usage of this macro.
- // Also, they aren't REALLY globals, becuase they're kept for EACH window,
- // which is why I use a bitfield, trying to keep this as small as
- // possible.)
-
- //*****************************************************************************
- // Function Prototypes
- //-----------------------------------------------------------------------------
-
- void DoWInit(WindowPeek window, long param, short varCode);
- void DoWDispose(WindowPeek window, long param);
- long DoWHit(WindowPeek window, long param);
- void DoWDraw(WindowPeek window, long param);
- void DoWCalcRgns(WindowPeek window, long param);
- void DoWGrow(WindowPeek window, long param);
- void DoWDrawGIcon(WindowPeek window, long param);
-
- void SyncPorts(void);
-
- //*****************************************************************************
- // Windoid Main Function
- //-----------------------------------------------------------------------------
- // This is the main entry point for all calls to this code resource. It
- // dispatches to routines that correspond to the message it is given.
- //-----------------------------------------------------------------------------
-
- pascal long main( short varCode, WindowPeek window,
- short message, long param ) {
- GrafPtr savePort;
- long result;
- Boolean isADrawMsg;
-
- // This sets up the appropriate drawing environment, but only for those
- // messages for which we actually need to draw.
- isADrawMsg = (message == wDraw || message == wHit || message == wDrawGIcon);
- if (isADrawMsg && WindData.hasCQD) {
- GetPort(&savePort);
- SyncPorts();
- }
-
- switch (message) {
- case wNew: DoWInit(window, param, varCode);
- break;
-
- case wDispose: DoWDispose(window, param);
- break;
-
- case wDraw: DoWDraw(window, param & 0xFFFF);
- break;
- // There's a tech note that says that for the draw message, only
- // the low-order word of param is set correctly, so we should do
- // this (AND with 0xFFFF) to be sure we're looking at the correct value.
-
- case wHit: result = DoWHit(window, param);
- break;
-
- case wCalcRgns: DoWCalcRgns(window, param);
- break;
-
- case wGrow: DoWGrow(window, param);
- break;
-
- case wDrawGIcon: DoWDrawGIcon(window, param);
- break;
- }
-
- if (isADrawMsg)
- SetPort(savePort);
-
- return result;
- }
-
- //*****************************************************************************
- // Environment-determining Routines
- //-----------------------------------------------------------------------------
- // These use SysEnvirons so we don't have to rely on Gestalt being available
- // and so MPW won't include that code in our resource.
-
- short HasSystem7( void ) {
- SysEnvRec theWorld;
- long theSysVers;
-
- if (SysEnvirons(1, &theWorld) == noErr) {
- theSysVers = (long)theWorld.systemVersion;
- return (theSysVers >= 0x0700);
- } else
- return false;
- }
-
- //-----------------------------------------------------------------------------
-
- short HasCQDraw( void ) {
- SysEnvRec theWorld;
-
- if ((SysEnvirons(1, &theWorld) == noErr) && theWorld.hasColorQD)
- return 1;
- else
- return 0;
- }
-
- //*****************************************************************************
- // SyncPorts
- //-----------------------------------------------------------------------------
- // Straight from the pages of _Macintosh Programming Secrets_, Second
- // Edition by Scott Knaster and Keith Rollin (page 425). (except that this
- // version doesn't check Gestalt, it will only be called if CQD is running)
- // This routines was added to 2.3. It makes sure the drawing environment
- // is set correctly if the system has color. This is not needed for the
- // code in this WDEF as it is, but if a DoWDrawGIcon handler is implemented,
- // this is needed to make sure the drawing environment is set as Apple
- // tells us it will be for drawing the gray, xor'ed border.
-
- void SyncPorts( void ) {
- GrafPtr bwPort;
- CGrafPtr colorPort;
-
- GetWMgrPort(&bwPort);
- GetCWMgrPort(&colorPort);
- SetPort((GrafPtr)colorPort);
-
- BlockMove(&bwPort->pnLoc, &colorPort->pnLoc, 10);
- BlockMove(&bwPort->pnVis, &colorPort->pnVis, 14);
- PenPat((ConstPatternParam)&bwPort->pnPat);
- BackPat((ConstPatternParam)&bwPort->bkPat);
- }
-
- //*****************************************************************************
- // Color Mixing Routines
- //-----------------------------------------------------------------------------
-
- void GetWctbColor( WindowPeek window, short partCode, RGBColor *theColor ) {
- // Given a partCode, return the RGBColor associated with it. (Using the
- // default window color table.)
- AuxWinHandle awHndl;
- short junkResult;
-
- junkResult = GetAuxWin((WindowPtr)window, &awHndl);
- *theColor = (**(WCTabHandle)((**awHndl).awCTable)).ctTable[partCode].rgb;
- }
-
- //-----------------------------------------------------------------------------
-
- void SetWctbColor( WindowPeek window, short partCode ) {
- RGBColor theColor;
-
- GetWctbColor(window, partCode, &theColor);
- RGBForeColor(&theColor);
- }
-
- //-----------------------------------------------------------------------------
- #pragma processor 68020
- // Note: this should be okay because this will only be called if we are
- // doing System 7 color, which requires Color Quickdraw, which is only
- // available on systems with 68020's or better. Again, this is done to
- // reduce code size. If it isn't compiled this way, several routines will
- // be added to handle the long integer arithmetic. We would like to avoid
- // that.
-
- void MixColor( const RGBColor *lightColor, const RGBColor *darkColor,
- short shade, RGBColor *result ) {
- shade = 0x0F - shade;
- // This is necessary because we give shades between light and
- // dark (0% is light), but for colors, $0000 is black and $FFFF
- // is dark.
-
- result->red = ((lightColor->red - darkColor->red) * shade / 15)
- + darkColor->red;
- result->green = ((lightColor->green - darkColor->green) * shade / 15)
- + darkColor->green;
- result->blue = ((lightColor->blue - darkColor->blue) * shade / 15)
- + darkColor->blue;
- }
-
- #pragma processor 68000
- //-----------------------------------------------------------------------------
-
- void AvgWctbColor( WindowPeek window, short light, short dark, short shade,
- RGBColor *theColor ) {
- // Mix two parts by the given shade, which is actually a value
- // between 0 (0%) and 15 (100%), return the RGBColor.
- RGBColor lightColor;
- RGBColor darkColor;
-
- GetWctbColor(window, light, &lightColor);
- GetWctbColor(window, dark, &darkColor);
- MixColor(&lightColor, &darkColor, shade, theColor);
- }
-
- //*****************************************************************************
- // Helper Functions
- //-----------------------------------------------------------------------------
-
- void FrameBox( const Rect *theRect ) {
- Rect tempRect = *theRect;
-
- FrameRect(theRect);
- InsetRect(&tempRect, 1, 1);
- EraseRect(&tempRect);
- }
-
- //-----------------------------------------------------------------------------
-
- void GetGlobalContentRect( WindowPeek window, Rect *contentRect ) {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort((GrafPtr)window);
- *contentRect = window->port.portRect;
- LocalToGlobal((Point*)&contentRect->top);
- LocalToGlobal((Point*)&contentRect->bottom);
- SetPort(savePort);
- }
-
- //*****************************************************************************
- // Routines to get Rects for title bar parts
- //-----------------------------------------------------------------------------
-
- void GetTitleBar( WindowPeek window, Rect *titleBar ) {
- *titleBar = (**(window->strucRgn)).rgnBBox;
-
- if (WindData.isHoriz) {
- // title bar on top
- titleBar->bottom = titleBar->top + kTitleHeight;
- titleBar->right -= 1; // shadow compensation
- } else {
- // title bar on left
- titleBar->right = titleBar->left + kTitleHeight;
- titleBar->bottom -= 1; // shadow compensation
- }
- }
-
- //-----------------------------------------------------------------------------
-
- void GetCloseBox( WindowPeek window, const Rect *titleRect, Rect *theRect ) {
- #pragma unused(window)
-
- *theRect = *titleRect;
- if (WindData.isHoriz)
- InsetRect(theRect, kGadgetMargin, kGadgetInset); // titlebar on top
- else
- InsetRect(theRect, kGadgetInset, kGadgetMargin); // titlebar on left
-
- theRect->bottom = theRect->top + kGadgetSize;
- theRect->right = theRect->left + kGadgetSize;
- }
-
- //-----------------------------------------------------------------------------
- #ifdef ALLOW_ZOOM
-
- void GetZoomBox( WindowPeek window, const Rect *titleRect, Rect *theRect ) {
- #pragma unused(window)
-
- *theRect = *titleRect;
- if (WindData.isHoriz)
- InsetRect(theRect, kGadgetMargin, kGadgetInset); // titlebar on top
- else
- InsetRect(theRect, kGadgetInset, kGadgetMargin); // titlebar on left
-
- theRect->top = theRect->bottom - kGadgetSize;
- theRect->left = theRect->right - kGadgetSize;
- }
-
- #endif
- //*****************************************************************************
- // Zoom handling
- //-----------------------------------------------------------------------------
- #ifdef ALLOW_ZOOM
-
- void SetZoomRects( WindowPeek window ) {
- Rect contRect;
-
- if (window->spareFlag) {
- GetGlobalContentRect(window, &contRect);
- WindData.wState.stdState = contRect;
- #ifdef MFI_ZOOM
- if (WindData.isHoriz) // titlebar on top
- contRect.bottom = contRect.top + 12;
- else // titlebar on left
- contRect.right = contRect.left + 12;
- #endif
- WindData.wState.userState = contRect;
- // the stdState and user state might be backwards from how they
- // would normally be used by an application. Check this for your
- // own use and change them if necessary.
- }
- }
-
- //-----------------------------------------------------------------------------
-
- long GetZoomHitType( WindowPeek window ) {
- Rect contRect;
- Rect stdRect;
-
- contRect = (**(window->contRgn)).rgnBBox;
- stdRect = WindData.wState.stdState;
- OffsetRect(&stdRect, -stdRect.left + contRect.left,
- -stdRect.top + contRect.top);
- // make topLeft the same for content and standard rects, and compare
-
- if (EqualRect(&contRect, &stdRect))
- return wInZoomIn; // go to user state (make small, MFI)
- else
- return wInZoomOut; // go to standard state (make normal, MFI)
- }
-
- #endif
- //*****************************************************************************
- // DoWInit -- Windoid initialization
- //-----------------------------------------------------------------------------
-
- void DoWInit( WindowPeek window, long param, short varCode ) {
- #pragma unused(param)
- Handle zoomStuff;
-
- window->spareFlag = false;
- zoomStuff = NewHandle(sizeof(WindoidData));
- if (zoomStuff) {
- window->dataHandle = zoomStuff;
- WindData.closeToggle = 0;
- WindData.hasCQD = HasCQDraw();
- WindData.isSystem7 = HasSystem7();
- WindData.hasTitlebar = true;
- WindData.ignoreHilite = false;
-
- #ifdef ALLOW_VERT
- WindData.isHoriz = (((varCode & 1) == 0) && ((varCode & 2) == 0));
- #else
- WindData.isHoriz = true;
- #endif
-
- #ifdef ALLOW_ZOOM
- WindData.zoomToggle = 0;
- window->spareFlag = ((zoomDocProc & varCode) != 0);
- SetZoomRects(window);
- #endif
-
- #ifdef ALWAYS_HILITE
- WindData.ignoreHilite = true;
- #endif
-
- #ifdef MACAPP_STYLE
- WindData.ignoreHilite = !((kMacApp_toggleTBar & varCode) != 0);
- #endif
-
- #ifdef THINK_STYLE
- if (((varCode & 7) != 0) && ((varCode & 7) != 2))
- WindData.hasTitlebar = false;
- #endif
- }
- }
-
- //*****************************************************************************
- // DoWDispose -- Windoid disposal
- //-----------------------------------------------------------------------------
-
- void DoWDispose( WindowPeek window, long param ) {
- #pragma unused(param)
-
- if (window->dataHandle)
- DisposeHandle(window->dataHandle);
- }
-
- //*****************************************************************************
- // DoWHit -- Windoid hit routine
- //-----------------------------------------------------------------------------
-
- long DoWHit( WindowPeek window, long param ) {
- Rect stdRect;
- Rect usrRect;
- Rect titleRect;
- Rect contentRect;
- Rect theRect;
- Point hitPt;
- long result;
-
- hitPt.v = HiWord(param);
- hitPt.h = LoWord(param);
-
- result = wNoHit;
- if (PtInRgn(hitPt, window->contRgn))
- result = wInContent;
- else {
- GetTitleBar(window, &titleRect);
- if (WindData.hasTitlebar && PtInRect(hitPt, &titleRect)) {
- result = wInDrag;
- if (WindData.ignoreHilite || window->hilited) {
- if (window->goAwayFlag) {
- GetCloseBox(window, &titleRect, &theRect);
- if (PtInRect(hitPt, &theRect))
- result = wInGoAway;
- }
- #ifdef ALLOW_ZOOM
- if (window->spareFlag) {
- GetZoomBox(window, &titleRect, &theRect);
- if (PtInRect(hitPt, &theRect)) {
- result = GetZoomHitType(window);
-
- // Calculate Offset for Zoom Rects (make sure they
- // are up to date)
- contentRect = (**(window->contRgn)).rgnBBox;
- stdRect = WindData.wState.stdState;
- usrRect = WindData.wState.userState;
-
- #ifdef STAYPUT_ZOOM
- OffsetRect(&(WindData.wState.stdState),
- contentRect.left - stdRect.left,
- contentRect.top - stdRect.top);
- OffsetRect(&(WindData.wState.userState),
- contentRect.left - usrRect.left,
- contentRect.top - usrRect.top);
- #else
- if (result == wInZoomIn) {
- OffsetRect(&(WindData.wState.stdState),
- contentRect.left - stdRect.left,
- contentRect.top - stdRect.top);
- } else {
- OffsetRect(&(WindData.wState.userState),
- contentRect.left - usrRect.left,
- contentRect.top - usrRect.top);
- }
- #endif
- }
- }
- #endif
- }
- }
- }
- return result;
- }
-
- //*****************************************************************************
- // DoWDraw -- Windoid drawing routines
- //-----------------------------------------------------------------------------
-
- void DrawCloseBox( WindowPeek window, short variation, Rect *theRect ) {
- RGBColor theColor;
- Rect tempRect;
-
- switch (variation) {
- case blackandwhite:
- FrameBox(theRect);
- break;
-
- case sys6color:
- SetWctbColor(window, wHiliteColor);
- GetWctbColor(window, wTitleBarColor, &theColor);
- RGBBackColor(&theColor);
- FrameBox(theRect);
- break;
-
- case sys7color:
- SetWctbColor(window, wTingeLight);
- tempRect = *theRect;
- tempRect.top++;
- tempRect.left++;
- FrameRect(&tempRect);
-
- SetWctbColor(window, wTingeDark);
-
- MoveTo(theRect->right - 1, theRect->top);
- LineTo(theRect->left, theRect->top);
- LineTo(theRect->left, theRect->bottom - 1);
-
- MoveTo(theRect->right - 2, theRect->top + 2);
- LineTo(theRect->right - 2, theRect->bottom - 2);
- LineTo(theRect->left + 2, theRect->bottom - 2);
-
- AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
- wCloseBoxColor, &theColor);
- RGBForeColor(&theColor);
- tempRect = *theRect;
- InsetRect(&tempRect, 2, 2);
- PaintRect(&tempRect);
-
- break;
- }
-
- }
-
- //*****************************************************************************
- // DrawZoomBox -- Draw zoom box
- //-----------------------------------------------------------------------------
- #ifdef ALLOW_ZOOM
-
- void DrawZoomBox( WindowPeek window, short variation, Rect *theRect ) {
- Rect tempRect;
- RGBColor theColor;
-
- switch (variation) {
- case blackandwhite:
- case sys6color:
- if (variation != blackandwhite) {
- SetWctbColor(window, wHiliteColor);
- GetWctbColor(window, wTitleBarColor, &theColor);
- RGBBackColor(&theColor);
- }
- FrameBox(theRect);
- tempRect = *theRect;
- tempRect.bottom -= 3;
- tempRect.right -= 3;
- FrameRect(&tempRect);
- break;
-
- case sys7color:
- DrawCloseBox(window, variation, theRect);
- SetWctbColor(window, wTingeDark);
-
- MoveTo(theRect->right - 4, theRect->top + 2);
- LineTo(theRect->right - 4, theRect->bottom - 4);
- LineTo(theRect->left + 2, theRect->bottom - 4);
- break;
- }
- }
-
- #endif
- //*****************************************************************************
- // DrawXedBox -- Draw close or zoom box with an X in it (or inverted in B&W)
- //-----------------------------------------------------------------------------
-
- void DrawXedBox( WindowPeek window, short variation, Rect *theRect ) {
- RGBColor theColor;
-
- switch (variation) {
- case blackandwhite:
- PaintRect(theRect);
- break;
-
- case sys6color:
- SetWctbColor(window, wHiliteColor);
- PaintRect(theRect);
- break;
-
- case sys7color:
- AvgWctbColor(window, wTingeLight, wTingeDark, wXedBoxPct, &theColor);
- RGBForeColor(&theColor);
- PaintRect(theRect);
-
- SetWctbColor(window, wFrameColor);
- FrameRect(theRect);
-
- MoveTo(theRect->left, theRect->top); // Draw the 'X'
- LineTo(theRect->right - 1, theRect->bottom - 1);
- MoveTo(theRect->right - 1, theRect->top);
- LineTo(theRect->left, theRect->bottom - 1);
- break;
- }
- }
-
- //*****************************************************************************
- // DrawTitlePat -- Draw pattern into the title bar
- //-----------------------------------------------------------------------------
- // This routine actually draws the pattern into the titlebar. Note: it
- // takes a Rect as a parameter (not by address) because it goes ahead and
- // modifies it. I figured this was no worse than needing to copy it into
- // a local variable, so I went ahead and did it this way.
-
- void DrawTitlePatPat( WindowPeek window, Rect titleRect ) {
- #pragma unused (window)
- Pattern titlePat;
- long patternSeed;
- Point corner;
- Rect tempRect;
- RgnHandle titleRgn;
- RgnHandle tempRgn;
-
- SetPt(&corner, titleRect.left, titleRect.top);
- LocalToGlobal(&corner);
-
- // Choose correct pattern, depending on position of window in global
- // coordinates. (Concept of new (2.3) version taken from _Macintosh
- // Programming Secrets_, Second Edition, by Scott Knaster and Keith
- // Rollin, page 423.)
- patternSeed = 0x00550055;
- if (!(corner.h & 1))
- patternSeed <<= 1;
- if (!(corner.v & 1))
- patternSeed <<= 8;
- *((long*)&titlePat + 1) = *(long*)&titlePat = patternSeed;
-
- // Draw the pattern into the titlebar, but only the areas needed
- // (i.e. don't draw into close, zoom boxes)
- titleRgn = NewRgn();
- tempRgn = NewRgn();
- RectRgn(titleRgn, &titleRect);
- InsetRgn(titleRgn, 1, 1);
- if (window->goAwayFlag) {
- GetCloseBox(window, &titleRect, &tempRect);
- RectRgn(tempRgn, &tempRect);
- DiffRgn(titleRgn, tempRgn, titleRgn);
- }
- if (window->spareFlag) {
- GetZoomBox(window, &titleRect, &tempRect);
- RectRgn(tempRgn, &tempRect);
- DiffRgn(titleRgn, tempRgn, titleRgn);
- }
- FillRgn(titleRgn, (ConstPatternParam)&titlePat);
- DisposeRgn(titleRgn);
- DisposeRgn(tempRgn);
-
- // -- used to be done this way, which would still work, but the new way
- // prevents a (barely noticeable) flash of the gadgets
- // InsetRect(&titleRect, 1, 1);
- // FillRect(&titleRect, &titlePat);
- }
-
- //-----------------------------------------------------------------------------
-
- void DrawTitlePat( WindowPeek window, short variation, Rect *titleRect ) {
- RGBColor theColor;
-
- switch (variation) {
- case blackandwhite:
- ForeColor(blackColor);
- BackColor(whiteColor);
- break;
-
- case sys6color:
- SetWctbColor(window, wHiliteColor);
- GetWctbColor(window, wTitleBarColor, &theColor);
- RGBBackColor(&theColor);
- break;
-
- case sys7color:
- AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
- wTitleBarLightPct, &theColor);
- RGBBackColor(&theColor);
- AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
- wTitleBarDarkPct, &theColor);
- RGBForeColor(&theColor);
- break;
- }
- DrawTitlePatPat(window, *titleRect);
- }
-
- //*****************************************************************************
- // CheckDisplay -- Check to see if we are using color title bars
- //-----------------------------------------------------------------------------
-
- Boolean CheckAvailable( WindowPeek window, short light, short dark,
- short count, short *ramp ) {
- // Given a light and dark index value, a count, and and an array of
- // 'percentage' values (0x0 to 0xF, or 0 to 15), see if each of the
- // values in the ramp maps to a different color on the screen. If not,
- // we need to use black-and-white.
-
- RGBColor theColor;
- short i;
- short result = true;
- short colorIndex = -1;
- short lastIndex;
-
- for (i = 0 ; i < count && result == true ; i++) {
- AvgWctbColor(window, light, dark, ramp[i], &theColor);
- lastIndex = colorIndex;
- colorIndex = Color2Index(&theColor);
- if (i > 0 && colorIndex == lastIndex)
- result = false;
- }
- return result;
- }
-
- //-----------------------------------------------------------------------------
-
- short CheckDisplay( short theDepth, short deviceFlags,
- GDHandle targetDevice, WindowPeek window ) {
- Boolean inColor;
- short result;
- RGBColor testColor;
- GDHandle saveDevice;
-
- inColor = WindData.hasCQD && (deviceFlags & (0x0001 << gdDevType));
-
- result = blackandwhite; // assume Black and White
- if (theDepth >= 4) {
- if (!WindData.isSystem7) {
- result = sys6color; // System 6.0.x Color
- } else {
- GetWctbColor(window, wTingeLight, &testColor);
- if (testColor.red != 0 || testColor.green != 0 || testColor.blue != 0)
- // check for B&W control panel setting, otherwise:
- result = sys7color; // System 7.0 Color
- }
- }
- // Note: Since I didn't find another way to see if the user had changed
- // the settings in the Color control panel to the Black-and-white setting,
- // I actually check to see if the rgb components of the light tinge color
- // are non-zero (which seemed to be the case with that setting).
-
- if (result == sys7color && inColor && theDepth <= 8) {
- short list[5] = { 0x00, 0x07, 0x08, 0x0A, 0x0D };
- // Make sure this array is allcated big enough for the largest ramp.
-
- result = blackandwhite;
- saveDevice = GetGDevice();
- SetGDevice(targetDevice);
- if (CheckAvailable(window, wHiliteColorLight, wHiliteColorDark, 5, list)) {
- list[0] = 0x00;
- list[1] = 0x01;
- list[2] = 0x04;
- if (CheckAvailable(window, wTitleBarLight, wTitleBarDark, 3, list)) {
- list[0] = 0x00;
- list[1] = 0x04;
- list[2] = 0x0F;
- if (CheckAvailable(window, wTingeLight, wTingeDark, 3, list))
- result = sys7color;
- }
- }
- SetGDevice(saveDevice);
- }
- // This part checks to see if there are 'enough' colors to draw the
- // title bar in color under System 7. It is supposed to do so in the
- // same way that Apple's system WDEF does. I essentially took the
- // assembly code that Apple released and tried to make this use the
- // same algorithm. Note: the values in list for the first CheckAvailable
- // call are set up in the variable declaration in the top of the routine.
- // Don't you just LOVE what C lets you do?
-
- return result;
- }
-
- //*****************************************************************************
- // Windoid drawing loop
- //-----------------------------------------------------------------------------
- // This information is used to communicate with DeviceLoop callback routine.
-
- typedef struct WDLDataRec {
- WindowPeek wdlWindow;
- long wdlParam;
- } WDLDataRec;
-
- //-----------------------------------------------------------------------------
- // This routine actually does the real work of the drawing of stuff into
- // the window.
-
- pascal void WindoidDrawLoop( short depth, short deviceFlags,
- GDHandle targetDevice, WDLDataRec *userData ) {
- #pragma unused(targetDevice)
- Rect titleRect;
- Rect tempRect;
- RGBColor theColor;
- WindowPeek window;
- short fancy;
-
- window = userData->wdlWindow;
- fancy = CheckDisplay(depth, deviceFlags, targetDevice, window);
-
- if (window->visible)
- switch (userData->wdlParam) {
- case wNoHit:
- BackColor(whiteColor);
-
- // Draw titlebar
- if (WindData.hasTitlebar) {
- GetTitleBar(window, &titleRect);
- switch (fancy) {
- case blackandwhite:
- ForeColor(blackColor);
- break;
-
- case sys6color:
- SetWctbColor(window, wFrameColor);
- break;
-
- case sys7color:
- if (WindData.ignoreHilite || window->hilited)
- SetWctbColor(window, wFrameColor);
- else {
- AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
- wInactiveFramePct, &theColor);
- RGBForeColor(&theColor);
- }
- break;
- }
- FrameRect(&titleRect);
- }
-
- if (WindData.ignoreHilite || window->hilited) {
- if (WindData.hasTitlebar)
- DrawTitlePat(window, fancy, &titleRect);
-
- // Draw close box
- if (window->goAwayFlag) {
- GetCloseBox(window, &titleRect, &tempRect);
- DrawCloseBox(window, fancy, &tempRect);
- }
- // Note: I have seen at least one windoid WDEF that is used
- // by some applications that does not utilize this flag.
- // In that case, I think it always had a close box (or it
- // might even have used the varcode to determine this, but
- // that wouldn't seem to be a good thing to do). Anyway, if
- // you always want the close box, just comment out the 'if'
- // line (and the close brace line) above.
-
- #ifdef ALLOW_ZOOM
- // Draw zoom box
- if (window->spareFlag) {
- GetZoomBox(window, &titleRect, &tempRect);
- DrawZoomBox(window, fancy, &tempRect);
- }
- #endif
- } else {
- tempRect = titleRect; // dimmed titlebar
- InsetRect(&tempRect,1,1);
- EraseRect(&tempRect);
- }
-
- // Draw content frame and shadow
- tempRect = (**(window->strucRgn)).rgnBBox;
- tempRect.bottom--;
- tempRect.right--;
-
- switch (fancy) {
- case blackandwhite:
- ForeColor(blackColor);
- break;
-
- case sys6color:
- SetWctbColor(window, wFrameColor);
- break;
-
- case sys7color:
- // If the window is not hilited, will use a gray shade
- // to draw the window outline in System 7 color.
- if (WindData.ignoreHilite || window->hilited)
- SetWctbColor(window, wFrameColor);
- else {
- AvgWctbColor(window, wHiliteColorLight, wHiliteColorDark,
- wInactiveFramePct, &theColor);
- RGBForeColor(&theColor);
- }
- break;
- }
- FrameRect(&tempRect);
-
- ForeColor(blackColor); // draw shadow
- MoveTo(tempRect.right, tempRect.top+1);
- LineTo(tempRect.right, tempRect.bottom);
- LineTo(tempRect.left + 1, tempRect.bottom);
- break;
-
- case wInGoAway: // toggle go-away
- GetTitleBar(window, &titleRect);
- GetCloseBox(window, &titleRect, &tempRect);
- if (WindData.closeToggle)
- DrawCloseBox(window, fancy, &tempRect);
- else
- DrawXedBox(window, fancy, &tempRect);
- break;
-
- #ifdef ALLOW_ZOOM
- default:
- if (window->spareFlag) { // toggle zoom box
- GetTitleBar(window, &titleRect);
- GetZoomBox(window, &titleRect, &tempRect);
- if (WindData.zoomToggle)
- DrawZoomBox(window, fancy, &tempRect);
- else
- DrawXedBox(window, fancy, &tempRect);
- }
- #endif
- }
- ForeColor(blackColor);
- BackColor(whiteColor);
- }
-
- //-----------------------------------------------------------------------------
-
- void DoWDraw( WindowPeek window, long param ) {
- WDLDataRec theUserData;
- GrafPtr savePort;
- RgnHandle drawRgn;
- Rect theRect;
- GDHandle theDevice;
- short inColor;
-
- GetPort(&savePort);
- SetPort((GrafPtr)window);
- drawRgn = window->strucRgn;
- SetPort(savePort);
-
- theUserData.wdlWindow = window;
- theUserData.wdlParam = param;
-
- if (WindData.isSystem7) {
- DeviceLoop(drawRgn, (DeviceLoopDrawingProcPtr)WindoidDrawLoop,
- (long)&theUserData, (DeviceLoopFlags)0);
- } else {
- inColor = 0;
- if (window && WindData.hasCQD) {
- GetGlobalContentRect(window, &theRect);
- theDevice = GetMaxDevice(&theRect);
-
- if (theDevice)
- WindoidDrawLoop((**(**theDevice).gdPMap).pixelSize, // <-- depth
- (**theDevice).gdFlags,
- theDevice, &theUserData);
- else
- WindoidDrawLoop(1, 0, nil, &theUserData);
-
- // Do this for pre-System 7. we call WindoidDrawLoop directly, giving
- // it the information on the device with maximum depth, hoping that
- // the results will be okay. Only reason it might not be is if you
- // have a System 6 color window that crosses two monitors that have
- // differing environments where one doesn't have enough colors to
- // show the color version. Here, the problem will be only cosmetic,
- // though. Note: I could have done my own device loop for this case,
- // but I figured it wasn't common enough for the expense.
- } else {
- WindoidDrawLoop(1, 0, nil, &theUserData);
- // Do this for 68000's
- }
- }
-
- if (window->visible) {
- switch (param) {
- case 0:
- // This is so param 0 doesn't get interpreted as a hit in the
- // zoom box, incorrectly.
- break;
-
- case wInGoAway: // toggle go-away
- WindData.closeToggle = !(WindData.closeToggle);
- break;
-
- #ifdef ALLOW_ZOOM
- default: // toggle zoom box
- WindData.zoomToggle = !(WindData.zoomToggle);
- break;
- #endif
- }
- }
- ForeColor(blackColor);
- BackColor(whiteColor);
- }
-
- //*****************************************************************************
- // DoWCalcRgns -- Windoid region calculating routine
- //-----------------------------------------------------------------------------
-
- void DoWCalcRgns( WindowPeek window, long param ) {
- #pragma unused(param)
- Rect contentRect;
- Rect structRect;
- RgnHandle tempRgn;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort((GrafPtr)window);
-
- contentRect = window->port.portRect;
- OffsetRect(&contentRect, -window->port.portBits.bounds.left,
- -window->port.portBits.bounds.top);
- RectRgn(window->contRgn, &contentRect);
-
- // start off with the structure equal to the content
- structRect = contentRect;
-
- // make it include the window frame and titlebar
- InsetRect(&structRect, -1, -1);
- if (WindData.hasTitlebar) {
- if (WindData.isHoriz)
- structRect.top -= kTitleHeight - 1;
- else
- structRect.left -= kTitleHeight - 1;
- }
- RectRgn(window->strucRgn, &structRect);
-
- // add the shadow to the structure
- OffsetRect(&structRect, 1, 1);
- tempRgn = NewRgn();
- RectRgn(tempRgn, &structRect);
- UnionRgn(tempRgn, window->strucRgn, window->strucRgn);
- DisposeRgn(tempRgn);
-
- SetPort(savePort);
- }
-
- //*****************************************************************************
- // DoWGrow -- Windoid region calculating routine
- //-----------------------------------------------------------------------------
- // I don't allow of a grow box in a windoid. If you want one, you will
- // have to implement these two routines.
-
- void DoWGrow( WindowPeek window, long param ) {
- #pragma unused(window, param)
- }
-
- //*****************************************************************************
- // DoWDrawGIcon -- Draw the grow icon in the lower right corner
- //-----------------------------------------------------------------------------
-
- void DoWDrawGIcon( WindowPeek window, long param ) {
- #pragma unused(window, param)
- }
-
- //*****************************************************************************
-